import json
import logging
import os
import time

import jinja2
import webapp2

from ndb_entity_helpers import entity_to_dict
from model.unnatural_name import UnnaturalName

# Configure the Jinja@ environment.
# Especially note the change to the variable escaping change from
# '{{}}' to '(())'.
_TEMPLATE_PATH = os.path.join(os.path.dirname(__file__), 'templates')
JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(_TEMPLATE_PATH),
    extensions=['jinja2.ext.autoescape'],
    variable_start_string='((',
    variable_end_string='))',
    autoescape=True)


def template_render(template, context):
    template = JINJA_ENVIRONMENT.get_template(template)
    return template.render(context)


class EntitiesHandler(webapp2.RequestHandler):
    def get(self):
        entities = UnnaturalName.query().order(UnnaturalName.natural_name).fetch()
        self.response.headers['Content-Type'] = 'application/json'

        output_list = list()
        for entity in entities:
            output_list.append(entity_to_dict(entity))
        self.response.out.write(json.dumps(output_list))


class EntityHandler(webapp2.RequestHandler):
    def get(self):
        the_id = self.request.get('id')
        entity = UnnaturalName.get_by_id(int(the_id))

        template_values = {
            'entity': entity_to_dict(entity)
        }

        self.response.out.write(template_render('entity_update.html', template_values))

    def post(self):
        the_id = self.request.get('id')

        if the_id and the_id != '':  # update existing entity

            entity = UnnaturalName.get_by_id(int(the_id))

            name = self.request.get('name')
            entity.name = name
            entity.put()

        else:  # a new entity

            entity_json = self.request.body
            entity_dict = json.loads(entity_json)

            entity = UnnaturalName(name=entity_dict['name'])
            entity.put()

        time.sleep(1)  # stall to alow eventual consistency
        self.response.headers.add('Content-Type', 'application/json')
        self.response.out.write(json.dumps(entity_to_dict(entity)))


class MainHandler(webapp2.RequestHandler):
    def get(self):
        """This method will diplay a list of saved entities, in natural sort order."""
        entities = UnnaturalName.query().order(UnnaturalName.natural_name).fetch()

        template_values = {
            "entities": entities,
        }

        self.response.out.write(template_render('index.html', template_values))


    def post(self):
        """This method will save an entity to the data store."""
        name = self.request.get('name')

        if not name:
            logging.error('No name given to incoming entity.')
            raise webapp2.HTTPException(
                "Bad Request, need to include the name of the entity.")

        entity = UnnaturalName(name=name)
        entity.put()

        # This is very dumb, but need time for data store to catch up.
        time.sleep(1)

        self.redirect('/', code=302)


app = webapp2.WSGIApplication([('/', MainHandler),
                               ('/entities', EntitiesHandler),
                               ('/entity', EntityHandler)],
                              debug=True)
